﻿using System.Reflection;

namespace DatabaseProxy.Attributes;

public static class ValidateExtensions
{
    /// <summary>
    /// 验证值是否符合约束
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public static Tuple<bool, Exception?> Validate<T>(this T t) where T : IDatabaseTable
    {
        bool result = true;
        var type = typeof(T);
        Exception? ex = null;
        foreach (var property in type.GetProperties())
        {
            foreach (var attribute in property.GetCustomAttributes<ValidateAttribute>())
            {
                if ((attribute is NotNullAttribute || attribute is PrimaryKeyAttribute) && !ValidateNotNull(property, t))
                {
                    result = false;
                    ex = new Exception($"这个对象的{property.Name}值不能为空");
                    break;
                }
                else if (attribute is StringLengthAttribute && !ValidateStringLength(property, t, ((StringLengthAttribute)attribute).Length))
                {
                    result = false;
                    ex = new Exception($"这个对象的{property.Name}值长度不能超过{((StringLengthAttribute)attribute).Length}");
                    break;
                }
            }
            if (!result) break;
        }
        return new Tuple<bool, Exception?>(result, ex);
    }
    /// <summary>
    /// 验证对象的属性值是否为空
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="property"></param>
    /// <param name="t"></param>
    /// <returns></returns>
    public static bool ValidateNotNull<T>(PropertyInfo property, T t) where T : IDatabaseTable => property.GetValue(t) != null;
    /// <summary>
    /// 验证对象的字符串属性值是否超出长度
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="property"></param>
    /// <param name="t"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    public static bool ValidateStringLength<T>(PropertyInfo property, T t, int length)
    {
        var result = true;
        var value = property.GetValue(t)?.ToString();
        if (property.PropertyType == typeof(string) && !string.IsNullOrEmpty(value))
        {
            result = value.Length <= length;
        }
        return result;
    }
}
